"use server";

import { z } from "zod";
import fs from "fs/promises";
import { createProduct } from "../service/products";
import { notFound, redirect } from "next/navigation";
import prisma from "../db/db";
import { revalidatePath } from "next/cache";
const fileSchema = z.instanceof(File, { message: "Please upload a file" });
const imageSchema = fileSchema.refine((file) => {
  return file.size === 0 || file.type.startsWith("image/");
});

const addSchema = z.object({
  name: z.string().min(1),
  description: z.string().min(1),
  priceInCents: z.coerce.number().int().min(1),
  file: fileSchema.refine((file) => file.size > 0, "Please upload a file"),
  image: imageSchema.refine((file) => file.size > 0, "Please upload an image"),
});

const saveFile = async ({ dir, url, file }) => {
  // 创建目录
  await fs.mkdir(dir, { recursive: true });
  // 文件保存路径
  const filePath = `${url}/${crypto.randomUUID()}-${file.name}`;
  // 保存文件
  await fs.writeFile(filePath, Buffer.from(await file.arrayBuffer()));
  return filePath;
};

export const addProduct = async (prev, formData) => {
  const res = addSchema.safeParse(Object.fromEntries(formData));
  if (!res.success) {
    return res.error.formErrors.fieldErrors;
  }
  const data = res.data;

  const [filePath, imagePath] = await Promise.all([
    saveFile({ dir: "products", url: "products", file: data.file }),
    // 默认存在 public 里
    saveFile({
      dir: "public/products",
      url: "public/products",
      file: data.image,
    }),
  ]);
  delete data.file;
  delete data.image;
  await createProduct({
    ...data,
    isAvailableForPurchase: false,
    filePath,
    imagePath,
  });
  redirect("/admin/products");
};

const updateSchema = addSchema.extend({
  id: z.string(),
  file: fileSchema.optional(),
  image: imageSchema.optional(),
});

export const updateProduct = async (prev, formData) => {
  const res = updateSchema.safeParse(Object.fromEntries(formData));
  if (!res.success) {
    return res.error.formErrors.fieldErrors;
  }
  const product = await prisma.product.findUnique({
    where: { id: res.data.id },
  });
  if (!product) {
    return notFound();
  }
  const data: any = {
    id: res.data.id,
    name: res.data.name,
    description: res.data.description,
    priceInCents: res.data.priceInCents,
  };
  let fileList = [];
  const fn = async () => {};
  if (res.data.file && res.data.file.size > 0) {
    // 有新file 删除旧的，上传新的
    await fs.unlink(product.filePath);
    fileList.push(
      saveFile({ dir: "products", url: "products", file: res.data.file })
    );
  } else {
    fileList.push(fn());
  }
  if (res.data.image && res.data.image.size > 0) {
    await fs.unlink(product.imagePath);
    fileList.push(
      saveFile({
        dir: "public/products",
        url: "public/products",
        file: res.data.image,
      })
    );
  } else {
    fileList.push(fn());
  }

  const [filePath, imagePath] = await Promise.all(fileList);
  if (filePath) {
    data.filePath = filePath;
  }
  if (imagePath) {
    data.imagePath = imagePath;
  }
  await prisma.product.update({
    where: { id: data.id },
    data,
  });
  // 页面做了请求数据库的缓存
  // 但是当增删改的时候，还是要重新请求数据库 **********
  revalidatePath("/products");
  revalidatePath("/");

  redirect("/admin/products");
};

// actions just for form???
// export const toggleProductAvailability = async (data) => {
//   await updateProduct(data);
// };

// export const deleteProduct = async (id) => {
//   await deleteProduct(id);
// };
